package com.ztjava.core.base;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.xiaoleilu.hutool.date.DateUtil;
import com.ztjava.core.Constant;
import com.ztjava.core.client.Client;
import com.ztjava.core.tool.ViewTool;

public class BaseService {
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List treeLevel(List treeList,Integer parent_id){
		Model m;
		List list = new ArrayList<>();
		for(int i=0;i<treeList.size();i++){
			m = (Model)treeList.get(i);
			if(m.getInt("parent_id").equals(parent_id)){
				((Model)treeList.get(i)).put("children", treeLevel(treeList, m.getInt("id")));
				list.add(treeList.get(i));
			}
		}
		return list;
	}
	public String getPara(Map<String,String[]> paramMap,String field,String defaultValue){
		if(!paramMap.containsKey(field)){
			return defaultValue;
		}
		return paramMap.get(field)[0];
	}
	public Integer getParaToInt(Map<String,String[]> paramMap,String field,Integer defaultValue){
		if(!paramMap.containsKey(field)){
			return defaultValue;
		}
		return Integer.parseInt(paramMap.get(field)[0]);
	}
	//fields格式：title*3 keyword*2 des*1
	public Ret searchSql(String keyword,String fields){
		Ret ret = Ret.create();
		String[] keywordArr = keyword.split(" ");
		String[] fieldArr = fields.split(" ");
		String where = "";
		String order = "";
		for(int j=0;j<fieldArr.length;j++){
			if(fieldArr[j].trim().equals("")){
				continue;
			}
			String[] itemArr = fieldArr[j].trim().split("\\*");
			for(int i=0;i<keywordArr.length;i++){
				if(keywordArr[i].trim().equals("")){
					continue;
				}
				if(!where.equals("")){
					where = where + " or ";
					order = order + "+";
				}
				String field = "`"+itemArr[0]+"`";
				if(itemArr[0].indexOf(".")>-1){
					String[] arr2 = itemArr[0].split("\\.");
					field = arr2[0]+".`"+ arr2[1]+"`";
				}
				where = where +field+" like '%"+keywordArr[i].trim()+"%'";
				order = order+ "if(InStr("+field+",'"+keywordArr[i].trim()+"')>0,"+itemArr[1]+",0)";
			}
		}
		if(!where.equals("")){
			where = " and ("+where+")";
			order = " order by "+order+" desc";
		}
		ret.set("where",where);
		ret.set("order",order);
		return ret;
	}
	
	/***
	 * 批量删除
	 * @param tablename
	 * @param ids
	 */
	public void batchDelete(String tablename,String[] ids){
		batchDelete(tablename, "id", ids);
	}
	/***
	 * 批量删除
	 * @param tablename
	 * @param primaryKey
	 * @param ids
	 */
	public void batchDelete(String tablename,String primaryKey,String[] ids){
		for(String key:ids){
			Db.deleteById(tablename,primaryKey,Integer.parseInt(key));
		}
	}
	/***
	 * 检查重复
	 * @param model
	 * @param tablename
	 * @param fields
	 * @return
	 */
	public Ret checkRepeat(Model<?> model,String tablename,String[]... fields){
		return checkRepeat(model,tablename,"",fields);
	}
	/***
	 * 检查重复
	 * @param model
	 * @param tablename
	 * @param whereParam
	 * @param fields
	 * @return
	 */
	public Ret checkRepeat(Model<?> model,String tablename,String whereParam,String[]... fields){
		String where = "";
		Ret ret = Ret.create();
		Record repeat;
		for(String[] item:fields){
			if(model.get(item[0])==null){
				continue;
			}
			where = " where "+item[0]+"=?";
			where = where + " " + whereParam;
			
			if(model.get("id")!=null){
				where = where + " and id<>"+model.getInt("id");
			}
			repeat = Db.findFirst("select id from "+tablename+where,model.get(item[0]));
			if(repeat!=null){
				ret.set(Constant.RESULT,Constant.ERROR);
				ret.set(Constant.MESSAGE, item[1]);
				return ret;
			}
		}
		ret.set(Constant.RESULT,Constant.SUCCESS);
		return ret;
	}
	public String orderby(String pre,Client client, Map<String,String[]> paramMap){
		return" order by "+pre+getPara(paramMap,client.getSortName(),"id")+" "+getPara(paramMap,client.getSortOrder(),"desc");
	}
	public String orderby(Client client, Map<String,String[]> paramMap){
		return orderby("",client, paramMap);
	}
	
	static final Object[] NULL_PARA_ARRAY = new Object[0];
	public static final String like = "like";
	public static final String like_left = "like_left";
	public static final String like_multiple = "like_multiple";
	public static final String notnull = "notnull";
	public static final String eq = "=";
	public static final String gt = ">";
	public static final String gte = ">=";
	public static final String lt = "<";
	public static final String lte = "<=";
	public static final String un = "<>";
	//自动组合查询参数
	//field,type,sqlfield
	public Object[] whereParam(Map<String,String[]> paramMap, String[]... field){
		List<String[]> list = new ArrayList<String[]>();
		String value = "";
		for(String[] item:field){
			if(!paramMap.containsKey(item[0])){
				continue;
			}
			if(paramMap.get(item[0])[0].trim().equals("")){
				continue;
			}
			list.add(item);
		}
		if(list.size()==0) return NULL_PARA_ARRAY;
		Object[] param = new Object[list.size()];
		Integer i = 0;
		for(String[] item:list){
			value = paramMap.get(item[0])[0].trim();
			switch (item[1]) {
				case like:
					value= "%"+value+"%";
					break;
				case like_left:
					value= value+"%";
					break;
				case like_multiple:
					value= "%,"+value+",%";
					break;
				case notnull:
					value = null;
					break;
				default:
					break;
			}
			param[i]= value;
			i = i + 1;
		}
		return param;
	}
	public String whereSql(Map<String,String[]> paramMap, String[]... field){
		String where = "";
		String value = "";
		String param = "";
		for(String[] item:field){
			if(!paramMap.containsKey(item[0])){
				continue;
			}
			value = paramMap.get(item[0])[0].trim();
			if(value.equals("")){
				continue;
			}
			if(item.length>2){
				param = item[2];
			}else {
				param = item[0];
			}
			switch (item[1]) {
				case like:
					where = where + " and "+param+" like ? ";
					break;
				case like_left:
					where = where + " and "+param+" like ? ";
					break;
				case like_multiple:
					where = where + " and "+param+" like ? ";
					break;
				case notnull:
					where = where + " and "+param+" is not ? ";
					break;
				default:
					where = where + " and "+param+item[1]+"? ";
					break;
			}
		}
		return where;
	}
	
	/***
	 * list数据转换(column,BASEDATA)
	 * @param list
	 * @param rule
	 */
	//rule:column,BASEDATA
	public void changeBasedata(List<?> list,String[]... rule){
		if(rule==null||rule.length==0){
			return;
		}
		Object value;
		Map<String,Map<String,JSONObject>> baseDataAll = new HashMap<String, Map<String,JSONObject>>();
		Map<String,JSONObject> basedata;
		Cache cache = Redis.use();
		String column;
		for(int i=0;i<list.size();i++){
			for(String[] item:rule){
				value = ((Model<?>)list.get(i)).get(item[0]);
				if(value==null) continue;
				if(!baseDataAll.containsKey(item[1])){
					Map<String,JSONObject> newbase = cache.hget(Constant.R_BASEDATA, item[1]);
					baseDataAll.put(item[1], newbase);
				}
				basedata = baseDataAll.get(item[1]);
				if(basedata==null) continue;
				if(basedata.get(value.toString())==null) continue;
				column = item[0];
				if(item.length>2){
					column = column + item[2];
				}else {
					column = column + "_cn";
				}
				((Model<?>)list.get(i)).put(column, basedata.get(value.toString()).getString("name"));
			}
		}
	}

	public void changeBasedata(Model<?> model,String[]... fields){
		if(fields==null||fields.length==0||model == null){
			return;
		}
		String value = "";
		Map<String,JSONObject> map;
		Cache cache = Redis.use();
		for(int i=0;i<fields.length;i++){
			for(String[] item:fields){
				value = model.getStr(item[0]);
				map = cache.hget(Constant.R_BASEDATA, item[1]);
				if(value!=null&&map!=null&&map.get(value.toString())!=null){
					model.put(item[0]+"_cn",map.get(value.toString()).getString("name"));
				}
			}
			
		}
	}

	public void changeMultiple(List<?> list,String[]... rule){
		if(rule==null||rule.length==0){
			return;
		}
		Object value;
		Map<String,Map<String,JSONObject>> baseDataAll = new HashMap<String, Map<String,JSONObject>>();
		Map<String,JSONObject> basedata;
		Cache cache = Redis.use();
		String column;
		for(int i=0;i<list.size();i++){
			for(String[] item:rule){
				value = ((Model<?>)list.get(i)).get(item[0]);
				if(value==null) continue;
				if(!baseDataAll.containsKey(item[1])){
					Map<String,JSONObject> newbase = cache.hget(Constant.R_BASEDATA, item[1]);
					baseDataAll.put(item[1], newbase);
				}
				basedata = baseDataAll.get(item[1]);
				if(basedata==null) continue;
				column = item[0];
				if(item.length>2){
					column = column + item[2];
				}else {
					column = column + "_cn";
				}
				String[] arr = value.toString().split(",");
				String show = "";
				for(String v:arr){
					if(v.trim().equals("")) continue;
					if(basedata.get(v.trim())==null) continue;
					show = show +  basedata.get(v.trim()).getString("name")+",";
				}
				if(!show.equals("")) show = show.substring(0,show.length()-1);
				((Model<?>)list.get(i)).put(column, show);
			}
		}
	}
	public void changeMultiple(Model model,String[]... rule){
		if(rule==null||rule.length==0){
			return;
		}
		Object value;
		Map<String,Map<String,JSONObject>> baseDataAll = new HashMap<String, Map<String,JSONObject>>();
		Map<String,JSONObject> basedata;
		Cache cache = Redis.use();
		String column;
		for(String[] item:rule){
			value = model.get(item[0]);
			if(value==null) continue;
			if(!baseDataAll.containsKey(item[1])){
				Map<String,JSONObject> newbase = cache.hget(Constant.R_BASEDATA, item[1]);
				baseDataAll.put(item[1], newbase);
			}
			basedata = baseDataAll.get(item[1]);
			if(basedata==null) continue;
			column = item[0];
			if(item.length>2){
				column = column + item[2];
			}else {
				column = column + "_cn";
			}
			String[] arr = value.toString().split(",");
			String show = "";
			for(String v:arr){
				if(v.trim().equals("")) continue;
				if(basedata.get(v.trim())==null) continue;
				show = show +  basedata.get(v.trim()).getString("name")+",";
			}
			if(!show.equals("")) show = show.substring(0,show.length()-1);
			model.put(column, show);
		}
	}
	/***
	 * 会员信息转换
	 * @param model
	 * @param field
	 *{"field","column"}
	 */
	//数据字段、用户字段
	public void changeUser(List<? extends Model<?>> list,String[]... field){
		if(field==null||field.length==0){
			return;
		}
		Integer user_id;
		JSONObject json ;
		Cache cache = Redis.use();
		Map<String,JSONObject> userMap = new HashMap<>();
		for(int i=0;i<list.size();i++){
			for(String[] item:field){
				user_id = list.get(i).getInt(item[0]);
				if(!userMap.containsKey(user_id+"")){
					if(!cache.hexists(Constant.R_USER, user_id+"")) continue;
					JSONObject user = cache.hget(Constant.R_USER, user_id+"");
					userMap.put(user_id+"", user);
				}
				json = userMap.get(user_id+"");
				list.get(i).put(item[0]+"_"+item[1],json.getString(item[1]));
			}
		}
	}
	@SuppressWarnings("rawtypes")
	public void changeUser(Model model,String[]...field){
		if(field==null||field.length==0||model==null){
			return;
		}
		Cache cache = Redis.use();
		for(String[] item:field){
			Integer user_id = model.getInt(item[0]);
			JSONObject json = cache.hget(Constant.R_USER, user_id+"");
			if(json==null){
				continue;
			}
			model.put(item[0]+"_"+item[1],json.getString(item[1]));
		}
	}
	/***
	 * 日期格式化
	 * @param list
	 * @param field
	 */
	protected final static String DATETIME_CHANGE = "DATETIME_CHANGE";
	public void changeDatetime(List<?> list,String[]... field){
		if(field==null||field.length==0){
			return;
		}

		Timestamp time;
		for(int i=0;i<list.size();i++){
			for(String[] item:field){
				time = ((Model<?>)list.get(i)).getTimestamp(item[0]);
				if(time!=null){
					if(item[1].equals(DATETIME_CHANGE)){
						((Model<?>)list.get(i)).put(item[0]+"_change",ViewTool.dateChange(time));
					}else {
						((Model<?>)list.get(i)).put(item[0]+"_format",DateUtil.format(time,item[1]));
					}
					
				}
			}
		}
	}
	
	public void databaseValues(List<?> list,String[]... rule){
		Cache cache = Redis.use();
		Map<String,Map<String,JSONObject>> baseDataAll = new HashMap<String, Map<String,JSONObject>>();
		Map<String,JSONObject> basedata;
		Object value;
		for(int i=0;i<list.size();i++){
			for(String[] item:rule){
				value =  ((Model<?>)list.get(i)).get(item[0]);
				if(value==null||value.toString().equals("")) continue;
				if(!baseDataAll.containsKey(item[1])){
					Map<String,JSONObject> newbase = cache.hget(Constant.R_BASEDATA, item[1]);
					baseDataAll.put(item[1], newbase);
				}
				basedata = baseDataAll.get(item[1]);
				String[] arr = value.toString().split(",");
				List<JSONObject> dataList = new ArrayList<>();
				for(int j=0;j<arr.length;j++){
					if(arr[j].trim().equals("")) continue;
					if(!basedata.containsKey(arr[j].trim())) continue;
					dataList.add(basedata.get(arr[j].trim()));
				}
				((Model<?>)list.get(i)).put(item[0]+"_list", dataList);
			}
		}
		
	}
}
